package gr.gsis.efmy.model;

import gr.gsis.efmy.model.annotation.Alphanumeric;
import gr.gsis.efmy.model.annotation.Amount;
import gr.gsis.efmy.model.annotation.Numeric;

import java.util.ArrayList;
import java.util.List;

/*
 * 				ΠΕΡΙΓΡΑΦΗ RECORD ΟΡΙΣΤΙΚΗΣ ΔΗΛΩΣΗΣ ΚΑΙ ΒΕΒΑΙΩΣΗΣ ΑΠΟΔΟΧΩΝ 
 * 								ΕΠΙΚΕΦΑΛΙΔΑ ΑΡΧΕΙΟΥ
 * 
 * 		------------------------------------------------------------------------------	
 * 		| A/A | ΠΕΡΙΓΡΑΦΗ ΠΕΔΙΟΥ 		|    ΘΕΣΗ   | ΜΟΡΦΗ  | ΤΙΜΕΣ-ΠΑΡΑΤΗΡΗΣΕΙΣ 	 |
 * 		|----------------------------------------------------------------------------|
 * 		|					   			| ΑΠΟ | ΕΩΣ |		 |					  	 |		
 * 		| 1.1 | Τύπος Record	   			|  1  |  1  |   9    |         0		  	 |	
 *      | 1.2 | Όνομα αρχείου			|  2  |  9  |  X(8)  |		 JL10		  	 |
 *      | 1.3 | Ημερομηνία δημιουργίας		| 10  | 17  |  9(8)  |	    YYYYMMDD         |
 *      | 1.4 | Αρ. κύκλου τρεξίματος		| 18  | 21  |  9(4)  | 2007 για τη χρήση 2007 |
 *      | 1.5 | FILLER    				| 22  | 170 | X(149) | 					  	 |
 *      ------------------------------------------------------------------------------
 */
public class PayrollTaxAggregate {
	
	private Header header;

	private Details details;
	
	private Totals totals;
	
	private List<WageDetails> wageDetails;
	
	public PayrollTaxAggregate header(Header header) {
		this.header = header;
		return this;
	}
	
	public PayrollTaxAggregate header(String creationDate, Short fiscalYear) {
		this.header = new Header(creationDate, fiscalYear);
		return this;
	}
	
	public PayrollTaxAggregate details(Details details) {
		this.details = details;
		return this;
	}
	
	public PayrollTaxAggregate details(Short year, String lastname, 
			String firstname, String middlename, String companyOrIndividualFlag,
			String afm, String businessType, String addrCity, String addrStreet,
			String addrNumber, Short addrZipCode) {
		this.details = new Details(year, lastname, firstname, middlename, 
				companyOrIndividualFlag, afm, businessType, addrCity, 
				addrStreet, addrNumber, addrZipCode);
		return this;
	}
	
	public PayrollTaxAggregate totals(Totals totals) {
		this.totals = totals;
		return this;
	}
	
	public PayrollTaxAggregate totals(Double grossEarnings, Double totalDeductions, 
			Double netEarnings, Double totalWithheldTax, Double stamp,
			Double ogaStamp, Double totalTax, Double ogaTotalWithheldTax, 
			Double ogaTotalTax) {
		this.totals = new Totals(grossEarnings, totalDeductions, 
				netEarnings, totalWithheldTax, stamp, ogaStamp, 
				totalTax, ogaTotalWithheldTax, ogaTotalTax);
		return this;
	}
	
	public PayrollTaxAggregate wageDetails(List<WageDetails> wageDetails) {
		this.wageDetails = wageDetails;
		return this;
	}
	
	public void addWageDetails(String afm, String lastname,
			String firstname, String middlename, String addrCity,
			String addrStreet, String addrNumber, Short addrZipCode,
			EarningsType earningsType, Double grossEarnings, Double stamp,
			Double ogaStamp, Double detentionsExcludingTax,
			Double netEarnings, Double withheldTax, Double tax,
			String branch, Short totalEmploymentDays,
			Double ogaWithheldTax, Double ogaTax) {
	
		if (null == wageDetails) {
			this.wageDetails = new ArrayList<WageDetails>();
		}
		
		this.wageDetails.add(
				new WageDetails(afm, lastname, firstname, 
						middlename, addrCity, addrStreet, addrNumber, 
						addrZipCode, earningsType, grossEarnings, stamp,
						ogaStamp, detentionsExcludingTax, netEarnings, 
						withheldTax, tax, branch, totalEmploymentDays,
						ogaWithheldTax, ogaTax));
	}
	
	public class Header {

		public final Short recordType = new Short((short) 0);
		
		public final String fileName = "JL10    ";
		
		@Numeric(length=8)
		public String creationDate;
		
		@Numeric(length=4)
		public Short fiscalYear;
		
		public final String filler = DataUtils.createFiller(149);
		
		private Header(String creationDate, Short fiscalYear) {
			this.creationDate = creationDate;
			this.fiscalYear = fiscalYear;
		}
		
	}
	
	public class Details {

		private final Short recordType = new Short((short) 1);
		
		@Numeric(length=4)
		private Short year;
		
		@Alphanumeric(length=18)
		private String lastname;
		
		@Alphanumeric(length=9)
		private String firstname;
		
		@Alphanumeric(length=3)
		private String middlename;
		
		@Alphanumeric(length=1)
		private String companyOrIndividualFlag;
		
		@Numeric(length=9)
		private String afm;
		
		@Alphanumeric(length=16)
		private String businessType; 
		
		@Alphanumeric(length=10)
		private String addrCity;
		
		@Alphanumeric(length=16)
		private String addrStreet;
		
		@Alphanumeric(length=5)
		private String addrNumber;
		
		@Numeric(length=5)
		private Short addrZipCode;
		
		private final String filler = DataUtils.createFiller(73);

		private Details(Short year, String lastname, String firstname,
				String middlename, String companyOrIndividualFlag, String afm,
				String businessType, String addrCity, String addrStreet,
				String addrNumber, Short addrZipCode) {
			this.year = year;
			this.lastname = lastname;
			this.firstname = firstname;
			this.middlename = middlename;
			this.companyOrIndividualFlag = companyOrIndividualFlag;
			this.afm = afm;
			this.businessType = businessType;
			this.addrCity = addrCity;
			this.addrStreet = addrStreet;
			this.addrNumber = addrNumber;
			this.addrZipCode = addrZipCode;
		}
		
	}
	
	public class Totals {
		
		private final Short recordType = new Short((short) 2);
		
		@Amount(length=13)
		private Double grossEarnings;
		
		@Amount(length=13)
		private Double totalDeductions;
		
		@Amount(length=13)
		private Double netEarnings;
		
		@Amount(length=12)
		private Double totalWithheldTax;
		
		@Amount(length=11)
		private Double stamp;
		
		@Amount(length=10)
		private Double ogaStamp;
		
		@Amount(length=12)
		private Double totalTax;
		
		@Amount(length=11)
		private Double ogaTotaWithheldlTax;
		
		@Amount(length=11)
		private Double ogaTotalTax;
		
		private final String filler = DataUtils.createFiller(45);

		private Totals(Double grossEarnings, Double totalDeductions,
				Double netEarnings, Double totalWithheldTax, Double stamp,
				Double ogaStamp, Double totalTax, Double ogaTotaWithheldlTax,
				Double ogaTotalTax) {
			this.grossEarnings = grossEarnings;
			this.totalDeductions = totalDeductions;
			this.netEarnings = netEarnings;
			this.totalWithheldTax = totalWithheldTax;
			this.stamp = stamp;
			this.ogaStamp = ogaStamp;
			this.totalTax = totalTax;
			this.ogaTotaWithheldlTax = ogaTotaWithheldlTax;
			this.ogaTotalTax = ogaTotalTax;
		}
	}
	
	public class WageDetails {
		
		private final Short recordType = new Short((short) 3);
		
		@Numeric(length=9)
		private String afm;
		
		private String filler1 = DataUtils.createFiller(1);

		@Alphanumeric(length=18)
		private String lastname;
		
		@Alphanumeric(length=9)
		private String firstname;
		
		@Alphanumeric(length=3)
		private String middlename;
		
		//Address
		
		@Alphanumeric(length=10)
		private String addrCity;
		
		@Alphanumeric(length=16)
		private String addrStreet;
		
		@Alphanumeric(length=5)
		private String addrNumber;
		
		@Numeric(length=5)
		private Short addrZipCode;
		
		//Amounts
		private EarningsType earningsType;
		
		@Amount(length=8)
		private Double grossEarnings;
		
		@Amount(length=6)
		private Double stamp;
		
		@Amount(length=5)
		private Double ogaStamp;
		
		@Amount(length=7)
		private Double detentionsExcludingTax;
		
		@Amount(length=8)
		private Double netEarnings;
		
		@Amount(length=7)
		private Double withheldTax;
		
		@Amount(length=7)
		private Double tax;
		
		@Alphanumeric(length=6)
		private String branch;
		
		@Numeric(length=3)
		private Short totalEmploymentDays;
		
		@Amount(length=6)
		private Double ogaWithheldTax;
		
		@Amount(length=6)
		private Double ogaTax;
		
		private final String filler2 = DataUtils.createFiller(4);

		private WageDetails(String afm, String lastname,
				String firstname, String middlename, String addrCity,
				String addrStreet, String addrNumber, Short addrZipCode,
				EarningsType earningsType, Double grossEarnings, Double stamp,
				Double ogaStamp, Double detentionsExcludingTax,
				Double netEarnings, Double withheldTax, Double tax,
				String branch, Short totalEmploymentDays,
				Double ogaWithheldTax, Double ogaTax) {
			this.afm = afm;
			this.filler1 = filler1;
			this.lastname = lastname;
			this.firstname = firstname;
			this.middlename = middlename;
			this.addrCity = addrCity;
			this.addrStreet = addrStreet;
			this.addrNumber = addrNumber;
			this.addrZipCode = addrZipCode;
			this.earningsType = earningsType;
			this.grossEarnings = grossEarnings;
			this.stamp = stamp;
			this.ogaStamp = ogaStamp;
			this.detentionsExcludingTax = detentionsExcludingTax;
			this.netEarnings = netEarnings;
			this.withheldTax = withheldTax;
			this.tax = tax;
			this.branch = branch;
			this.totalEmploymentDays = totalEmploymentDays;
			this.ogaWithheldTax = ogaWithheldTax;
			this.ogaTax = ogaTax;
		}
	}
	
	public Header getHeader() {
		return this.header;
	}
	
	public Details getDetails() {
		return this.details;
	}
	
	public Totals getTotals() {
		return this.totals;
	}
	
	public List<WageDetails> getWageDetails() {
		return this.wageDetails;
	}
}


